﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace SmarTypeWin
{
    class Analyser
    {
        struct wordWeight
        {
            public string word;
            public double weight;
            public wordWeight(string wd)
            {
                this.word = wd;
                weight = 0;
                char[] array = wd.ToCharArray();
                int[] intArray;
                for (int i = 0; i < array.Length; i++)
                {
                    intArray = getLetterWeight(array[i]);
                    this.weight += intArray[0] + intArray[1];
                }
            }
            public wordWeight(string wd, int wt)
            {
                this.word = wd;
                this.weight = wt;
            }
            public wordWeight(string wd, double wt)
            {
                this.word = wd;
                this.weight = wt;
            }
        }

        static List<wordWeight> weights = new List<wordWeight>();
        static List<wordWeight> possibilities = new List<wordWeight>();

        static public String getRightText(char[] text)
        {
            int a = 0;
            char[] aux;
            double weightcompare = 0;
            int[] arrayint;
            int[] arrayA;
            int[] arrayB;
            List<wordWeight> possibilitiesWeights = new List<wordWeight>();
            bool has;
            possibilities = new List<wordWeight>();
            if(weights.Count == 0)
                loadWordWeights();

            for (int i = 0; i < text.Length; i++)
            {
                arrayint = getLetterWeight(text[i]);
                if (arrayint.Length > 0)
                    a += arrayint[0] + arrayint[1];
            }
            foreach (wordWeight weight in weights)
            {
                if (weight.weight < a + a / 5 && weight.weight > a - a / 5)
                {
                    possibilities.Add(weight);
                }
            }
            
            foreach (wordWeight str in possibilities)
            {
                aux = str.word.ToCharArray();
                weightcompare = 0;
                for (int i = 0; i < Math.Min(text.Length, aux.Length); i++)
                {
                    has = false;
                    if (i != 0)
                        if (aux[i - 1] == text[i])
                            has = true;
                    if (i > 1)
                        if (aux[i - 2] == text[i])
                            has = true;
                    if (i < aux.Length - 3)
                        if (aux[i + 2] == text[i])
                            has = true;
                    if (i != aux.Length - 1)
                        if (aux[i + 1] == text[i])
                            has = true;
                    if (aux[i] == text[i])
                        has = true;
                    if (!has || !text.Contains(aux[i]))
                        weightcompare++;
                    //arrayA = getLetterWeight(text[i]);
                    //arrayB = getLetterWeight(aux[i]);
                    //weightcompare += Math.Sqrt( Math.Pow((arrayA[0] - arrayB[0]) , 2) + Math.Pow((arrayA[1] - arrayB[1]), 2));
                }
                weightcompare += Math.Abs(text.Length - aux.Length);
                //if (str.weight == a && weightcompare > 0)
                //    weightcompare /= 3;
                if(weightcompare >= 0 && weightcompare <= 3)
                    possibilitiesWeights.Add(new wordWeight(str.word, weightcompare));
            }

            possibilitiesWeights = possibilitiesWeights.OrderBy(p => p.weight).ToList();

            wordWeight chosen = possibilitiesWeights.FirstOrDefault();
            
            if (chosen.weight <= 10 && possibilitiesWeights.Count > 0)
                return chosen.word;

            return new string(text);
        }

        static void loadWordWeights()
        {
            StreamReader strReader = new StreamReader(@"D:/words.txt");
            string word = "";
            while (word != null)
            {
                word = strReader.ReadLine();
                if (word != null)
                {
                    word = word.Trim().ToLower();
                    weights.Add(new wordWeight(word));
                }
            }
            weights.Add(new wordWeight("work"));
            weights.Add(new wordWeight("fast"));
            weights.Add(new wordWeight("flex"));
            weights.Add(new wordWeight("vision"));
            weights.Add(new wordWeight("implementation"));
            weights.Add(new wordWeight("content"));
            weights.Add(new wordWeight("function"));
            weights.Add(new wordWeight("quick"));
            weights.Add(new wordWeight("brown"));
            weights.Add(new wordWeight("fox"));
            weights.Add(new wordWeight("jump"));
            weights.Add(new wordWeight("over"));
            weights.Add(new wordWeight("the"));
            weights.Add(new wordWeight("lazy"));
            weights.Add(new wordWeight("dog"));
            weights.Add(new wordWeight("god"));
            weights.Add(new wordWeight("huge"));
            weights.Add(new wordWeight("return"));
        }
        static int[] getLetterWeight(char c)
        {
            switch (c)
            {
                case 'q':
                    return new int[] { 0, 0 };
                case 'w':
                    return new int[] { 0, 1 }; 
                case 'e':
                    return new int[] { 0, 2 }; 
                case 'r':
                    return new int[] { 0, 3 }; 
                case 't':
                    return new int[] { 0, 4 }; 
                case 'y':
                    return new int[] { 0, 5 }; 
                case 'u':
                    return new int[] { 0, 6 }; 
                case 'i':
                    return new int[] { 0, 7 }; 
                case 'o':
                    return new int[] { 0, 8 }; 
                case 'p':
                    return new int[] { 0, 9 }; 
                case 'a':
                    return new int[] { 1, 0 }; 
                case 's':
                    return new int[] { 1, 1 }; 
                case 'd':
                    return new int[] { 1, 2 }; 
                case 'f':
                    return new int[] { 1, 3 };
                case 'g':
                    return new int[] { 1, 4 }; 
                case 'h':
                    return new int[] { 1, 5 }; 
                case 'j':
                    return new int[] { 1, 6 }; 
                case 'k':
                    return new int[] { 1, 7 }; 
                case 'l':
                    return new int[] { 1, 8 }; 
                case 'ç':
                    return new int[] { 1, 9 }; 
                case '\\':
                    return new int[] { 2, 0 }; 
                case 'z':
                    return new int[] { 2, 1 }; 
                case 'x':
                    return new int[] { 2, 2 }; 
                case 'c':
                    return new int[] { 2, 3 }; 
                case 'v':
                    return new int[] { 2, 4 }; 
                case 'b':
                    return new int[] { 2, 5 }; 
                case 'n':
                    return new int[] { 2, 6 }; 
                case 'm':
                    return new int[] { 2, 7 }; 
                case ',':
                    return new int[] { 2, 8 }; 
                case '.':
                    return new int[] { 2, 9 }; 
            }
            return new int [] { };
        }
    }
}
